﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.ComponentModel.Design;
using System.Windows.Forms.Design;
using OpenComposite.Base;

namespace OpenComposite.Controls
{
	public partial class SqlConnectionControl : UserControl
	{
		public SqlConnectionControl()
		{
			InitializeComponent();
			lblSQLInstance.Text = "SQL Server";
			txtSqlServer.Visible = true;
		}

		private bool _connectionOk = false;
		public bool IsConnectionOk
		{
			get { return _connectionOk; }
		}
		/// <summary>
		/// Gets a value indicating whether all fields are left empty.
		/// </summary>
		/// <value><c>true</c> if all fields are empty; otherwise, <c>false</c>.</value>
		public bool IsEmpty
		{
			get
			{
				bool isEmpty = false;
				bool dbEmpty = string.IsNullOrEmpty(txtDatabase.Text) || string.IsNullOrEmpty(txtSqlServer.Text);
				if ( checkWinAuthentication.Checked ) {
					isEmpty = dbEmpty;
				} else {
					isEmpty = dbEmpty && string.IsNullOrEmpty(txtDbUser.Text);
				}
				return isEmpty;
			}
		}
		public string UserName
		{
			get { return txtDbUser.Text; }
			set { txtDbUser.Text = value; }
		}
		public string Password
		{
			get { return txtDbPassword.Text; }
			set { txtDbPassword.Text = value; }
		}
		public string DatabaseServer
		{
			get { return txtSqlServer.Text; }
			set { txtSqlServer.Text = value; }
		}
		public string DatabaseName
		{
			get { return txtDatabase.Text; }
			set { txtDatabase.Text = value; }
		}
		public bool UseWindowsAuthentication
		{
			get { return checkWinAuthentication.Checked; }
			set { checkWinAuthentication.Checked = value; }
		}
		public string ConnectionString
		{
			get { return createConnectionString(); }
			set
			{
				SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(value);
				UseWindowsAuthentication = builder.IntegratedSecurity;
				UserName = builder.UserID;
				Password = builder.Password;
				DatabaseServer = builder.DataSource;
				DatabaseName = builder.InitialCatalog;
			}
		}

		private string createConnectionString()
		{
			SqlConnectionStringBuilder connBuilder = new SqlConnectionStringBuilder();
			connBuilder.ConnectTimeout = (int)numTimeOut.Value;
			connBuilder.DataSource = txtSqlServer.Text;
			connBuilder.InitialCatalog = txtDatabase.Text;
			connBuilder.PacketSize = 4096;
			connBuilder.IntegratedSecurity = checkWinAuthentication.Checked;
			if ( !checkWinAuthentication.Checked ) {
				connBuilder.PersistSecurityInfo = true;
				connBuilder.UserID = txtDbUser.Text;
				connBuilder.Password = txtDbPassword.Text;
			}
			return connBuilder.ConnectionString;
		}

		private bool testDBConn(bool bShowOKMsg)
		{
			string msg = "";
			using ( WorkingMsgBox wmsg = new WorkingMsgBox() ) {
				wmsg.Show("Testing SQL Connection...");
				using ( SqlConnection conn = new SqlConnection() ) {
					try {
						conn.ConnectionString = createConnectionString();
						conn.Open();
						_connectionOk = true;
					} catch ( Exception ex ) {
						msg += string.Format("Test connection to sql server '{0}' failed.{1}{1}{2}",
											 conn.DataSource, Environment.NewLine, ex.Message);
						_connectionOk = false;
					} finally {
						if ( conn.State == ConnectionState.Open ) conn.Close();
					}
				}
			}
			if ( msg.Length > 0 ) {
				MessageBox.Show(msg, "Test connection failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
				return false;
			} else if ( bShowOKMsg ) {
				MessageBox.Show("Test connection succeeded.", "Test connection", MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
			return true;
		}

		#region Invalidate On Change
		private void cmbSQLInstances_SelectedIndexChanged(object sender, EventArgs e)
		{
			_connectionOk = false;
		}

		private void txtSqlServer_TextChanged(object sender, EventArgs e)
		{
			_connectionOk = false;
		}

		private void txtDatabase_TextChanged(object sender, EventArgs e)
		{
			_connectionOk = false;
		}

		private void checkWinAuthentication_CheckedChanged(object sender, EventArgs e)
		{
			_connectionOk = false;
			CheckBox cb = sender as CheckBox;
			if ( cb == null )
				return;

			txtDbUser.Enabled = !cb.Checked;
			txtDbPassword.Enabled = !cb.Checked;
		}

		private void txtDbUser_TextChanged(object sender, EventArgs e)
		{
			_connectionOk = false;
		}

		private void txtDbPassword_TextChanged(object sender, EventArgs e)
		{
			_connectionOk = false;
		}
		#endregion

		private void btnTestConnection_Click(object sender, EventArgs e)
		{
			testDBConn(true);
		}
	}

	public class SqlConnectionControlDesigner : ParentControlDesigner
	{
	}
}
